package co.edu.usbcali.raju.games.chess.server;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.StringTokenizer;

import org.apache.log4j.Logger;

import co.edu.usbcali.raju.games.chess.client.IOutputXboardAdapter;
import co.edu.usbcali.raju.games.chess.controller.ChessController;

public class XBoardAdapter extends UnicastRemoteObject implements IXBoardAdapterR{
	
	public static final int NO_MODE=0;
	public static final int XBOARD_MODE=1;
	public static final int UCI_MODE=2;
	public static final int STARTED=0;
	public static final int RUNNING=1;
	public static final String IS_READY="isready";
	public static final String READY_OK="readyok";
	public static final String XBOARD="xboard";
	public static final String PROTOVER="protover";
	public static final String FEATURE="feature done=1";
	public static final String NEW="new";
	public static final String RANDOM="random";
	public static final String ACCEPTED="accepted";
	public static final String LEVEL="level";
	public static final String POST="post";
	public static final String HARD="hard";
	public static final String TIME="time";
	public static final String OTIM="otim";
	public static final String LETTERS="abcdefgh";
	public static final String MOVE="move";
	public static final String QUIT="quit";
	private int status; 
	private int mode;
	private int protocol;
	private ChessController controller;
	private IOutputXboardAdapter writer;

	public boolean running=true;
	
	Logger  logger;
	
	public XBoardAdapter() throws RemoteException {
		super();
		init();
	}

	public XBoardAdapter(ChessController controller) throws RemoteException {
		super();
		init();
		this.controller=controller;
	}
	
	public void init(){
		logger=Logger.getLogger(XBoardAdapter.class.getName());
	}

	public void processComand(String command){
		logger.debug("Comando de xboard:"+command);
		try{
			switch (mode){
			case NO_MODE: if(command.equals(XBOARD)){
				logger.debug("Pasando a modo xboard");
				mode=XBOARD_MODE;
			}
			break;
			case XBOARD_MODE:processXBoardCommand(command);
			break;	
			}
		}catch (Exception e){
			logger.error(e.getLocalizedMessage());
		}
	}
	
	public void processXBoardCommand(String command) throws RemoteException{
		logger.debug("Status:"+status);
		switch (status){
		case STARTED:processXBoardStarted(command);
		break;
		case RUNNING:processXBoardRunning(command);
		break;
		}
	}
	
	public void processUCIComand(String command) throws RemoteException{
		switch (status){
		case STARTED:processUCIStarted(command);
		break;
		}
	}
	
	public void processUCIStarted(String command) throws RemoteException{
		StringTokenizer st=new StringTokenizer(command);
		while(st.hasMoreTokens()){
			String string=st.nextToken();
			if(string.equals(IS_READY)){
				status=RUNNING;
				writer.write(READY_OK);
//				System.out.println(READY_OK);
			}
		}
	}

	public void processXBoardStarted(String command) throws RemoteException{
		logger.debug("Entro a started");
		StringTokenizer st=new StringTokenizer(command);
		if(st.hasMoreTokens()){
			String string=st.nextToken();
			if(string.equals(PROTOVER)){
				logger.debug("Definiendo el protocolo");
				protocol=Integer.parseInt(st.nextToken());
				status=RUNNING;
				logger.debug("Enviando:"+FEATURE);
				logger.debug("Status:"+status);
				writer.write(FEATURE);
//				System.out.println(FEATURE);
			}
		}
	}

	public void processXBoardRunning(String command) throws RemoteException{
		logger.debug("Entro a running");
		StringTokenizer st=new StringTokenizer(command);
		if(st.hasMoreTokens()){
			String string=st.nextToken();
			if(string.equals(ACCEPTED)){
				logger.debug("Entendido Accepted");
				st.nextToken();
			}else
			if(string.equals(NEW)){
				logger.debug("Inicio tablero en posicion inicial");
				controller.newBoard();
				logger.debug("Fin tablero en posicion inicial");
			}
			else if(string.equals(RANDOM)){
				logger.debug("Habilitando random");
				controller.setRandom(true);
			}
			else if(string.equals(LEVEL)){
				st.nextToken();
				st.nextToken();
				st.nextToken();
				logger.debug("Habilitando el nivel");
			}
			else if(string.equals(POST)){
				
			}
			else if(string.equals(HARD)){
			}
			else if(string.equals(TIME)){
				st.nextToken();
			}
			else if(string.equals(OTIM)){
				st.nextToken();
			}
			else if(string.equals(QUIT)){
				running=false;
			}
			else if(LETTERS.contains(string.substring(0,1))&&LETTERS.contains(string.substring(2,3))){
				logger.debug("Procesando jugada");
				controller.doMove(translate(string));
				String answer=controller.doMoveToNA();
				logger.debug("Engine reply:"+answer);
				writer.write(answer);
			}

		}
	}
 @Override
	public boolean isRunning() throws RemoteException{
		return running;
	}

	public void setRunning(boolean running) {
		this.running = running;
	}
	
	public String translate(String move){
		return move;
	}

	@Override
	public void registerClient(IOutputXboardAdapter writer) throws RemoteException {
		this.writer=writer;
	}
	


}
